# -*- coding:utf8 -*- #
# -----------------------------------------------------------------------------------
# ProjectName:  smalleel-api-tools
# FileName:     ftp_connect.py
# Author  :
# Datetime:     2023/1/30 17:41
# Description: 文件压缩上传服务器解压
# -----------------------------------------------------------------------------------

import os
import zipfile
import paramiko
from common.util.configUtil.configUtil import ConfigUtil
from common.util.loggerUtil.logUtil import LoggerUtil


class FtpUtil:
    def __init__(self, option: str):
        """
        初始化连接服务器
        :param option:需要写进哪个系统的日志文件 (The system log file that needs to be written to)
        """
        self.log = LoggerUtil(option)
        self.config = ConfigUtil()
        self.remote_path = self.config.get_ftp_info('remote_path')
        self.ssh = paramiko.SSHClient()  # 创建SSH对象
        self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())  # 允许连接不在know_hosts文件中的主机
        self.transport = paramiko.Transport((self.config.get_ftp_info("host"), int(self.config.get_ftp_info('port'))))
        self.transport.connect(username=self.config.get_ftp_info('username'),
                               password=self.config.get_ftp_info('password'))

    # noinspection PyUnreachableCode
    def upload_file(self, uploadFileName: str) -> None:
        """
        上传文件
        :param uploadFileName:需要上传文件的名字
        :return:
        """
        targetFilePath = self.config.get_html_path(uploadFileName) + uploadFileName
        self.__zip_file(targetFilePath)
        sftp = paramiko.SFTPClient.from_transport(self.transport)
        try:
            sftp.put(f"{targetFilePath}.zip", self.remote_path + (uploadFileName + ".zip"))  # 上传
            print(f"======{uploadFileName}上传完成======")
            self.log.info(f"{uploadFileName}压缩包已上传至服务器！")
            self.__unzip(uploadFileName)
        except Exception as e:
            self.log.error(e)
            raise e
        self.transport.close()
        self.ssh.close()

    def __zip_file(self, targetFilePath: str) -> None:
        """
            压缩文件
        :param targetFilePath: 需要压缩文件的路径
        :return:
        """
        name = targetFilePath.split("\\")[-1]
        z = zipfile.ZipFile(targetFilePath + '.zip', 'w', zipfile.ZIP_DEFLATED)
        for dirPath, dirNames, fileNames in os.walk(targetFilePath):
            fpath = dirPath.replace(targetFilePath, '')
            fpath = fpath and fpath + os.sep or ''
            for fileName in fileNames:
                z.write(os.path.join(dirPath, fileName), fpath + fileName)
        print(f"======{name}压缩成功======")
        self.log.info(f"{name}压缩包已压缩！")
        z.close()

    def __unzip(self, fileName: str) -> None:
        """
            服务器解压文件
        :param fileName: 文件名
        :return:
        """
        self.ssh._transport = self.transport
        dsc = f"{self.remote_path}{fileName}.zip"
        stdin, stdout, stderr = self.ssh.exec_command(
            f'cd {self.remote_path};unzip -o {dsc} -d ./{fileName};rm -rf {dsc}')
        result = stdout.read().decode()
        if result.strip() != '':
            print(f"======{fileName}解压成功======")
            self.log.info(f"{fileName}压缩包已在服务器解压并删除！")
        else:
            print(f"Error message:{stderr.read().decode()}")
            self.log.error(f"{fileName}解压失败,失败原因{stderr.read().decode()}")
        self.ssh.close()


if __name__ == '__main__':
    FtpUtil("smalleelLogPath").upload_file("smalleel_report")
    FtpUtil("merchantLogPath").upload_file("merchant_report")
